#ifndef COMMON_H
#define COMMON_H

#include <cassert>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>

namespace GenBen {

#ifndef GENBEN_PLATFORM_PSP
#define ASSERT(x) assert(x)
#else
#define ASSERT(x) if(!(x)) { FILE* out = fopen("assert.txt", "w"); fprintf(out, "%s", #x); fclose(out); exit(0); }
#endif

typedef std::string string;

typedef long long int64;
typedef unsigned long long uint64;
typedef int int32;
typedef unsigned int uint32;
typedef unsigned int uint;
typedef short int16;
typedef unsigned short uint16;
typedef char int8;  
typedef unsigned char uint8;
typedef unsigned char byte;

// MSVC already has these defined
#ifndef GENBEN_PLATFORM_WIN
#define MININT8   ((int8)  0x80)
#define MAXINT8   ((int8)  0x7f)
#define MAXUINT8   ((uint8) 0xff)

#define MININT16   ((int16)  0x8000)
#define MAXINT16   ((int16)  0x7fff)
#define MAXUINT16   ((uint16) 0xffff)

#define MININT32   ((int32)  0x80000000)
#define MAXINT32   ((int32)  0x7fffffff)
#define MAXUINT32   ((uint32) 0xffffffff)

#define MININT64   ((int64) 0x8000000000000000LL)
#define MAXINT64   ((int64) 0x7fffffffffffffffLL)
#define MAXUINT64  ((uint64) 0xffffffffffffffffULL)
#endif

class Color
{
public:
	Color() : r(0.0f), g(0.0f), b(0.0f), a(1.0f) {};
	Color(float r, float g, float b) : r(r), g(g), b(b), a(1.0f) {};
	Color(float r, float g, float b, float a) : r(r), g(g), b(b), a(a) {};
	Color(const Color& col) : r(col.r), g(col.g), b(col.b), a(col.a) {};

	float r, g, b, a;
};

template <typename T>
class Vector2
{
public:
	Vector2() {};
	Vector2(T x, T y) : x(x), y(y) {};
	Vector2(const Vector2<T>& v) : x(v.x), y(v.y) {};

	Vector2<T> operator+(const Vector2<T>& v)
	{
		return Vector2<T>(x + v.x, y + v.y);
	}

	Vector2<T> operator-(const Vector2<T>& v)
	{
		return Vector2<T>(x - v.x, y - v.y);
	}

	T length()
	{
		return (T)sqrt(x*x + y*y);
	}

	T x, y;
};

template <typename T>
class Rect
{
public:
	Rect() {};
	Rect(T x1, T y1, T x2, T y2) : min(x1, y1), max(x2, y2) {};
	Rect(const Rect<T>& r) : min(r.min), max(r.max) {};

	T width() const { return max.x - min.x; };
	T height() const { return max.y - min.y; };

	static Rect<T> zero() { static Rect<T> z(T(0), T(0), T(0), T(0)); return z; };
	Vector2<T> min, max;
};

typedef Vector2<int> VectorI;
typedef Vector2<int> SizeI;
typedef Vector2<float> VectorF;
typedef Vector2<float> SizeF;
typedef Rect<int> RectI;
typedef Rect<float> RectF;

class noncopyable
{
protected:
	noncopyable() {}
	~noncopyable() {}
private: 
	noncopyable( const noncopyable& );
	const noncopyable& operator=( const noncopyable& );
};

} // namespace

#endif

